package com.lingnan.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lingnan.dto.JobPositionPageDto;
import com.lingnan.dto.JobPositionQueryParam;
import com.lingnan.dto.JobPositionSaveParam;
import com.lingnan.entity.po.CompanyHr;
import com.lingnan.entity.po.JobApplication;
import com.lingnan.entity.po.JobPosition;
import com.lingnan.entity.po.JobSeeker;
import com.lingnan.entity.vo.Result;
import com.lingnan.exception.MyException;
import com.lingnan.feign.UserFeignClient;
import com.lingnan.service.JobPositionService;
import com.lingnan.mapper.JobPositionMapper;
import com.lingnan.mapper.JobApplicationMapper;
import com.lingnan.utils.LoginContextHolder;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
* @author abc20
* @description 针对表【job_position(企业招聘职位表)】的数据库操作Service实现
* @createDate 2025-07-21 14:35:19
*/
@Service
public class JobPositionServiceImpl extends ServiceImpl<JobPositionMapper, JobPosition>
    implements JobPositionService{

    @Autowired
    private JobPositionMapper jobPositionMapper;

    @Autowired
    private JobApplicationMapper JobApplicationMapper;
    @Autowired
    private UserFeignClient userFeignClient;


    @Override
    public boolean incrementViewCount(Long id) {
        return jobPositionMapper.incrementViewCount(id) > 0;
    }

    @Override
    public JobPositionPageDto saveJobPosition(JobPositionSaveParam saveParam) {
        JobPosition jobPosition = new JobPosition();
        BeanUtils.copyProperties(saveParam, jobPosition);

        if (saveParam.getId() != null) {
            // 编辑模式
            jobPosition.setUpdatedAt(new Date());
            // 可以添加更新者ID，如果有当前用户信息的话

            String loginId = (String)LoginContextHolder.get("loginId");
            Result<CompanyHr> hr = userFeignClient.getHrByUserId(Long.valueOf(loginId));
            jobPosition.setUpdateId(hr.getData().getId());

            boolean updateResult = updateById(jobPosition);
            if (!updateResult) {
                MyException.cast("职位更新失败");
            }
        } else {
            // 新增模式
            jobPosition.setCreatedAt(new Date());
            jobPosition.setViewCount(0);

            boolean saveResult = save(jobPosition);
            if (!saveResult) {
                MyException.cast("职位保存失败");
            }
        }

        // 返回完整的职位信息
        return getJobPositionById(jobPosition.getId());
    }

    @Override
    public JobPositionPageDto getJobPositionById(Long id) {
        if (id == null) {
            MyException.cast("职位ID不能为空");
        }

        JobPositionPageDto result = jobPositionMapper.selectJobPositionById(id);
        if (result == null) {
            MyException.cast("职位信息不存在");
        }

        return result;
    }

    @Override
    public void deleteJobPosition(Long id) {
        if (id == null) {
            MyException.cast("职位ID不能为空");
        }

        // 检查职位是否存在
        JobPosition jobPosition = getById(id);
        if (jobPosition == null) {
            MyException.cast("职位信息不存在");
        }

        // 检查是否有投递记录
        QueryWrapper<JobApplication> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("position_id", id);
        Long applicationCount = JobApplicationMapper.selectCount(queryWrapper);

        if (applicationCount > 0) {
            MyException.cast("该职位已有投递记录，无法删除");
        }

        boolean deleteResult = removeById(id);
        if (!deleteResult) {
            MyException.cast("职位删除失败");
        }
    }

    @Override
    public void batchDeleteJobPosition(List<Long> ids) {
        if (ids == null || ids.isEmpty()) {
            MyException.cast("删除的职位ID列表不能为空");
        }

        // 检查是否有投递记录
        QueryWrapper<JobApplication> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("position_id", ids);
        Long applicationCount = JobApplicationMapper.selectCount(queryWrapper);

        if (applicationCount > 0) {
            MyException.cast("部分职位已有投递记录，无法删除");
        }

        boolean deleteResult = removeByIds(ids);
        if (!deleteResult) {
            MyException.cast("批量删除职位失败");
        }
    }

    @Override
    public void updateJobPositionStatus(Long id, Integer status) {
        if (id == null) {
            MyException.cast("职位ID不能为空");
        }

        if (status == null || status < 0 || status > 2) {
            MyException.cast("职位状态值无效");
        }

        JobPosition jobPosition = new JobPosition();
        jobPosition.setId(id);
        jobPosition.setStatus(status);
        jobPosition.setUpdatedAt(new Date());

        boolean updateResult = updateById(jobPosition);
        if (!updateResult) {
            MyException.cast("职位状态更新失败");
        }
    }

    @Override
    public IPage<JobPositionPageDto> getListByQueryParam(int pageNum, int pageSize, JobPositionQueryParam queryParam) {
        // 创建分页对象
        Page<JobPositionPageDto> page = new Page<>(pageNum, pageSize);

        // 构建查询条件
        QueryWrapper<JobPosition> queryWrapper = buildQueryWrapper(queryParam);

        // 执行自定义查询
        IPage<JobPositionPageDto> result = jobPositionMapper.selectJobPositionPage(page, queryWrapper);

        return result;
    }

    @Override
    public Map<String, Integer> getAllJobTypeCounts() {
        // 1. 构建查询条件：选择非空类型字段并进行分组统计
        QueryWrapper<JobPosition> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("CASE WHEN type IS NULL OR type = '' THEN '未知类型' ELSE type END AS type",
                        "COUNT(*) AS count")
                .groupBy("CASE WHEN type IS NULL OR type = '' THEN '未知类型' ELSE type END");

        // 2. 执行分组查询
        List<Map<String, Object>> typeCounts = listMaps(queryWrapper);

        // 3. 转换为Map<String, Integer>格式
        Map<String, Integer> resultMap = new LinkedHashMap<>();
        for (Map<String, Object> map : typeCounts) {
            String type = (String) map.get("type");
            Long count = (Long) map.get("count");
            resultMap.put(type, count.intValue());
        }

        return resultMap;
    }

    /**
     * 构建查询条件
     */
    private QueryWrapper<JobPosition> buildQueryWrapper(JobPositionQueryParam queryParam) {
        QueryWrapper<JobPosition> queryWrapper = new QueryWrapper<>();

        if (queryParam == null) {
            return queryWrapper;
        }

        // 职位名称模糊查询
        if (StringUtils.hasText(queryParam.getTitle())) {
            queryWrapper.like("jp.title", queryParam.getTitle());
        }

        // 工作地点模糊查询
        if (StringUtils.hasText(queryParam.getLocation())) {
            queryWrapper.like("jp.location", queryParam.getLocation());
        }

        // 薪资范围精确查询
        if (StringUtils.hasText(queryParam.getSalaryRange())) {
            queryWrapper.eq("jp.salary_range", queryParam.getSalaryRange());
        }

        // 经验要求精确查询
        if (StringUtils.hasText(queryParam.getExpRequirement())) {
            queryWrapper.eq("jp.exp_requirement", queryParam.getExpRequirement());
        }

        // 职位类型精确查询
        if (StringUtils.hasText(queryParam.getType())) {
            queryWrapper.eq("jp.type", queryParam.getType());
        }

        // 学历要求精确查询
        if (StringUtils.hasText(queryParam.getEduRequirement())) {
            queryWrapper.eq("jp.edu_requirement", queryParam.getEduRequirement());
        }

        // 状态查询
        if (queryParam.getStatus() != null) {
            queryWrapper.eq("jp.status", queryParam.getStatus());
        }

        // 企业ID查询
        if (queryParam.getCompanyId() != null) {
            queryWrapper.eq("jp.company_id", queryParam.getCompanyId());
        }

        // HR ID查询
        if (queryParam.getHrId() != null) {
            queryWrapper.eq("jp.hr_id", queryParam.getHrId());
        }

        // 排序处理
        handleOrderBy(queryWrapper, queryParam);

        return queryWrapper;
    }

    /**
     * 处理排序
     */
    private void handleOrderBy(QueryWrapper<JobPosition> queryWrapper, JobPositionQueryParam queryParam) {
        if (StringUtils.hasText(queryParam.getOrderBy())) {
            boolean isAsc = !"DESC".equalsIgnoreCase(queryParam.getSortOrder());

            switch (queryParam.getOrderBy()) {
                case "createdAt":
                    queryWrapper.orderBy(true, isAsc, "jp.created_at");
                    break;
                case "updatedAt":
                    queryWrapper.orderBy(true, isAsc, "jp.updated_at");
                    break;
                case "viewCount":
                    queryWrapper.orderBy(true, isAsc, "jp.view_count");
                    break;
                case "sendCount":
                    queryWrapper.orderBy(true, isAsc, "send_count");
                    break;
                default:
                    queryWrapper.orderByDesc("jp.created_at");
                    break;
            }
        } else {
            // 默认按创建时间倒序
            queryWrapper.orderByDesc("jp.created_at");
        }
    }

    @Override
    public List<JobPosition> getJobPositionByIds(List<Long> ids) {
        LambdaQueryWrapper<JobPosition> QueryWrapper = new LambdaQueryWrapper<>();
        QueryWrapper.in(JobPosition::getId, ids);
        return this.list(QueryWrapper);
    }

    @Override
    public Map<String, Double> getJobTypePercentages() {
        // 获取所有职位类型及数量
        Map<String, Integer> typeCounts = getAllJobTypeCounts();

        // 计算总数
        int total = typeCounts.values().stream().mapToInt(Integer::intValue).sum();

        // 计算百分比
        Map<String, Double> percentages = new LinkedHashMap<>();
        typeCounts.forEach((type, count) -> {
            double percentage = (double) count / total * 100;
            percentages.put(type, percentage);
        });

        return percentages;
    }
}




